package de.nordakademie.hausarbeit.crudframework.serializer;

import com.google.inject.Inject;
import com.google.inject.Provider;
import de.nordakademie.hausarbeit.crudframework.domainDsl.Application;
import de.nordakademie.hausarbeit.crudframework.domainDsl.DataType;
import de.nordakademie.hausarbeit.crudframework.domainDsl.DomainDslPackage;
import de.nordakademie.hausarbeit.crudframework.domainDsl.Entity;
import de.nordakademie.hausarbeit.crudframework.domainDsl.PackageDeclaration;
import de.nordakademie.hausarbeit.crudframework.domainDsl.RefAttribute;
import de.nordakademie.hausarbeit.crudframework.domainDsl.RefByAttribute;
import de.nordakademie.hausarbeit.crudframework.domainDsl.SimpleAttribute;
import de.nordakademie.hausarbeit.crudframework.services.DomainDslGrammarAccess;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractDelegatingSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticNodeProvider.INodesForEObjectProvider;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;

@SuppressWarnings("all")
public class DomainDslSemanticSequencer extends AbstractDelegatingSemanticSequencer {

	@Inject
	private DomainDslGrammarAccess grammarAccess;
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == DomainDslPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case DomainDslPackage.APPLICATION:
				if(context == grammarAccess.getApplicationRule()) {
					sequence_Application(context, (Application) semanticObject); 
					return; 
				}
				else break;
			case DomainDslPackage.DATA_TYPE:
				if(context == grammarAccess.getDataTypeRule() ||
				   context == grammarAccess.getTypeRule()) {
					sequence_DataType(context, (DataType) semanticObject); 
					return; 
				}
				else break;
			case DomainDslPackage.ENTITY:
				if(context == grammarAccess.getEntityRule() ||
				   context == grammarAccess.getTypeRule()) {
					sequence_Entity(context, (Entity) semanticObject); 
					return; 
				}
				else break;
			case DomainDslPackage.PACKAGE_DECLARATION:
				if(context == grammarAccess.getPackageDeclarationRule()) {
					sequence_PackageDeclaration(context, (PackageDeclaration) semanticObject); 
					return; 
				}
				else break;
			case DomainDslPackage.REF_ATTRIBUTE:
				if(context == grammarAccess.getAttributeRule() ||
				   context == grammarAccess.getRefAttributeRule()) {
					sequence_RefAttribute(context, (RefAttribute) semanticObject); 
					return; 
				}
				else break;
			case DomainDslPackage.REF_BY_ATTRIBUTE:
				if(context == grammarAccess.getAttributeRule() ||
				   context == grammarAccess.getRefByAttributeRule()) {
					sequence_RefByAttribute(context, (RefByAttribute) semanticObject); 
					return; 
				}
				else break;
			case DomainDslPackage.SIMPLE_ATTRIBUTE:
				if(context == grammarAccess.getAttributeRule() ||
				   context == grammarAccess.getSimpleAttributeRule()) {
					sequence_SimpleAttribute(context, (SimpleAttribute) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     (name=ID packageDeclarations+=PackageDeclaration*)
	 */
	protected void sequence_Application(EObject context, Application semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     name=ID
	 */
	protected void sequence_DataType(EObject context, DataType semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, DomainDslPackage.Literals.TYPE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, DomainDslPackage.Literals.TYPE__NAME));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getDataTypeAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID superType=[Entity|ID]? attributes+=Attribute*)
	 */
	protected void sequence_Entity(EObject context, Entity semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=QualifiedName entities+=Entity*)
	 */
	protected void sequence_PackageDeclaration(EObject context, PackageDeclaration semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID refs?='refs' (one?='one' | many?='many') type=[Entity|ID])
	 */
	protected void sequence_RefAttribute(EObject context, RefAttribute semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID ref_by?='ref_by' (one?='one' | many?='many')? type=[Entity|ID])
	 */
	protected void sequence_RefByAttribute(EObject context, RefByAttribute semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID (type='String' | type='Integer' | type='Boolean' | type='Long'))
	 */
	protected void sequence_SimpleAttribute(EObject context, SimpleAttribute semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
}
